/**
 * 专业DBC解析器
 * 包含词法分析器、语法分析器和数据模型
 */

// ===== DBC词法分析器 =====
class DBCTokenizer {
    constructor(content) {
        this.content = content;
        this.position = 0;
        this.line = 1;
        this.column = 1;
        this.tokens = [];
    }

    tokenize() {
        this.tokens = [];
        
        while (!this.isAtEnd()) {
            this.skipWhitespace();
            
            if (this.isAtEnd()) break;
            
            const char = this.currentChar();
            
            // 跳过注释
            if (char === '/' && this.peek() === '/') {
                this.skipLine();
                continue;
            }
            
            // 字符串
            if (char === '"') {
                this.readString();
            }
            // 数字
            else if (this.isDigit(char) || (char === '-' && this.isDigit(this.peek()))) {
                this.readNumber();
            }
            // 标识符
            else if (this.isAlpha(char) || char === '_') {
                this.readIdentifier();
            }
            // 分隔符
            else if (this.isSeparator(char)) {
                this.addToken('SEPARATOR', char);
                this.advance();
            }
            // 其他字符
            else {
                this.advance();
            }
        }
        
        this.addToken('EOF', '');
        return this.tokens;
    }

    currentChar() {
        return this.content[this.position];
    }

    peek(offset = 1) {
        const pos = this.position + offset;
        return pos >= this.content.length ? '\0' : this.content[pos];
    }

    advance() {
        if (this.position < this.content.length) {
            if (this.currentChar() === '\n') {
                this.line++;
                this.column = 1;
            } else {
                this.column++;
            }
            this.position++;
        }
        return this.content[this.position - 1];
    }

    skipWhitespace() {
        while (!this.isAtEnd() && this.isWhitespace(this.currentChar())) {
            this.advance();
        }
    }

    skipLine() {
        while (!this.isAtEnd() && this.currentChar() !== '\n') {
            this.advance();
        }
        if (!this.isAtEnd()) this.advance(); // 跳过换行符
    }

    readString() {
        const start = this.position;
        this.advance(); // 跳过开始的引号
        
        let value = '';
        while (!this.isAtEnd() && this.currentChar() !== '"') {
            if (this.currentChar() === '\\') {
                this.advance();
                if (!this.isAtEnd()) {
                    const escaped = this.currentChar();
                    switch (escaped) {
                        case 'n': value += '\n'; break;
                        case 't': value += '\t'; break;
                        case 'r': value += '\r'; break;
                        case '\\': value += '\\'; break;
                        case '"': value += '"'; break;
                        default: value += escaped; break;
                    }
                    this.advance();
                }
            } else {
                value += this.currentChar();
                this.advance();
            }
        }
        
        if (!this.isAtEnd()) {
            this.advance(); // 跳过结束的引号
        }
        
        this.addToken('STRING', value);
    }

    readNumber() {
        const start = this.position;
        
        // 处理负号
        if (this.currentChar() === '-') {
            this.advance();
        }
        
        // 处理十六进制
        if (this.currentChar() === '0' && (this.peek() === 'x' || this.peek() === 'X')) {
            this.advance(); // 跳过 '0'
            this.advance(); // 跳过 'x'
            
            while (!this.isAtEnd() && this.isHexDigit(this.currentChar())) {
                this.advance();
            }
        } else {
            // 处理十进制数字
            while (!this.isAtEnd() && this.isDigit(this.currentChar())) {
                this.advance();
            }
            
            // 小数点
            if (!this.isAtEnd() && this.currentChar() === '.' && this.isDigit(this.peek())) {
                this.advance(); // 跳过小数点
                while (!this.isAtEnd() && this.isDigit(this.currentChar())) {
                    this.advance();
                }
            }
            
            // 科学计数法
            if (!this.isAtEnd() && (this.currentChar() === 'e' || this.currentChar() === 'E')) {
                this.advance();
                if (!this.isAtEnd() && (this.currentChar() === '+' || this.currentChar() === '-')) {
                    this.advance();
                }
                while (!this.isAtEnd() && this.isDigit(this.currentChar())) {
                    this.advance();
                }
            }
        }
        
        const value = this.content.substring(start, this.position);
        this.addToken('NUMBER', value);
    }

    readIdentifier() {
        const start = this.position;
        
        while (!this.isAtEnd() && (this.isAlphaNumeric(this.currentChar()) || this.currentChar() === '_')) {
            this.advance();
        }
        
        const value = this.content.substring(start, this.position);
        this.addToken('IDENTIFIER', value);
    }

    addToken(type, value) {
        this.tokens.push({
            type,
            value,
            line: this.line,
            column: this.column - value.length
        });
    }

    isAtEnd() {
        return this.position >= this.content.length;
    }

    isWhitespace(char) {
        return char === ' ' || char === '\t' || char === '\r' || char === '\n';
    }

    isDigit(char) {
        return char >= '0' && char <= '9';
    }

    isHexDigit(char) {
        return this.isDigit(char) || (char >= 'a' && char <= 'f') || (char >= 'A' && char <= 'F');
    }

    isAlpha(char) {
        return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z');
    }

    isAlphaNumeric(char) {
        return this.isAlpha(char) || this.isDigit(char);
    }

    isSeparator(char) {
        return char === ':' || char === ';' || char === ',' || char === '(' || char === ')' || 
               char === '[' || char === ']' || char === '|' || char === '+' || char === '-';
    }
}

// ===== CAN信号数据模型 =====
class CANSignal {
    constructor(name, startBit, length, byteOrder, signedness, factor, offset, min, max, unit, comment = '') {
        this.name = name;
        this.startBit = startBit;
        this.length = length;
        this.byteOrder = byteOrder; // 'Intel' 或 'Motorola'
        this.signedness = signedness; // 'signed' 或 'unsigned'
        this.factor = factor;
        this.offset = offset;
        this.min = min;
        this.max = max;
        this.unit = unit;
        this.comment = comment;
        this.multiplexInfo = null; // 多路复用信息
        this.valueTable = null; // 值表
        this.receivers = []; // 接收节点
    }

    setComment(comment) {
        this.comment = comment;
    }

    setValueTable(valueTable) {
        this.valueTable = valueTable;
    }

    setMultiplexInfo(info) {
        this.multiplexInfo = info;
    }

    calculatePhysicalValue(rawValue) {
        return rawValue * this.factor + this.offset;
    }

    extractValue(canData) {
        // 简化的位提取逻辑
        return (canData >> this.startBit) & ((1 << this.length) - 1);
    }
}

// ===== CAN消息帧数据模型 =====
class CANFrame {
    constructor(name, canId, dlc, comment = '') {
        this.name = name;
        this.canId = canId;
        this.dlc = dlc;
        this.comment = comment;
        this.signals = new Map(); // 信号映射
        this.transmitters = []; // 发送节点
        this.period = null; // 发送周期
    }

    addSignal(signal) {
        this.signals.set(signal.name, signal);
    }

    removeSignal(signalName) {
        this.signals.delete(signalName);
    }

    getSignal(signalName) {
        return this.signals.get(signalName);
    }

    hasSignal(signalName) {
        return this.signals.has(signalName);
    }

    getAllSignals() {
        return Array.from(this.signals.values());
    }

    setComment(comment) {
        this.comment = comment;
    }

    setPeriod(period) {
        this.period = period;
    }

    setTransmitters(transmitters) {
        this.transmitters = transmitters;
    }

    getFrameType() {
        return this.canId > 0x7FF ? 'Extended' : 'Standard';
    }
}

// ===== CAN数据库数据模型 =====
class CANDatabase {
    constructor(filename = '') {
        this.filename = filename;
        this.version = '';
        this.newSymbols = [];
        this.bitTiming = null;
        this.nodes = new Set(); // 节点集合
        this.frames = new Map(); // CAN帧映射（按ID）
        this.framesByName = new Map(); // CAN帧映射（按名称）
        this.globalAttributes = new Map(); // 全局属性
        this.warnings = []; // 解析警告
    }

    addFrame(frame) {
        this.frames.set(frame.canId, frame);
        this.framesByName.set(frame.name, frame);
    }

    removeFrame(canId) {
        const frame = this.frames.get(canId);
        if (frame) {
            this.frames.delete(canId);
            this.framesByName.delete(frame.name);
            return true;
        }
        return false;
    }

    getFrame(canId) {
        return this.frames.get(canId);
    }

    getFrameByName(name) {
        return this.framesByName.get(name);
    }

    hasFrame(canId) {
        return this.frames.has(canId);
    }

    getAllFrames() {
        return Array.from(this.frames.values());
    }

    addNode(nodeName) {
        this.nodes.add(nodeName);
    }

    addWarning(message, line = 0) {
        this.warnings.push({ message, line });
    }

    getStatistics() {
        let signalCount = 0;
        this.frames.forEach(frame => {
            signalCount += frame.signals.size;
        });

        return {
            frameCount: this.frames.size,
            signalCount: signalCount,
            nodeCount: this.nodes.size,
            warningCount: this.warnings.length
        };
    }
}

// ===== DBC语法分析器 =====
class DBCParser {
    constructor(tokenizer) {
        this.tokens = tokenizer.tokenize();
        this.current = 0;
        this.database = new CANDatabase();
        
        // 调试信息
        console.log('词法分析完成，token数量:', this.tokens.length);
        console.log('前10个token:', this.tokens.slice(0, 10));
    }

    parse() {
        try {
            while (!this.isAtEnd()) {
                if (this.check('IDENTIFIER')) {
                    this.parseTopLevelStatement();
                } else {
                    this.advance();
                }
            }
        } catch (error) {
            console.error('解析器错误:', error);
            this.database.addWarning(`解析错误: ${error.message}`, this.getCurrentLine());
        }

        // 调试信息
        console.log('解析完成:', {
            frames: this.database.frames.size,
            nodes: this.database.nodes.size,
            warnings: this.database.warnings.length
        });

        return this.database;
    }

    parseTopLevelStatement() {
        const identifier = this.peek().value;
        console.log('解析语句:', identifier, '位置:', this.current);

        try {
            switch (identifier) {
                case 'VERSION':
                    this.parseVersion();
                    break;
                case 'NS_':
                    this.parseNamespace();
                    break;
                case 'BS_':
                    this.parseBitTiming();
                    break;
                case 'BU_':
                    this.parseNodes();
                    break;
                case 'BO_':
                    this.parseMessage();
                    break;
                case 'SG_':
                    // SG_ 信号应该在消息定义内部处理，这里跳过
                    this.skipUntilNextStatement();
                    break;
                case 'CM_':
                    this.parseComment();
                    break;
                case 'BA_DEF_':
                    this.parseAttributeDefinition();
                    break;
                case 'BA_':
                    this.parseAttributeValue();
                    break;
                case 'VAL_':
                    this.parseValueTable();
                    break;
                case 'BO_TX_BU_':
                    this.parseTransmitters();
                    break;
                default:
                    this.skipUntilNextStatement();
                    break;
            }
        } catch (error) {
            this.database.addWarning(`解析 ${identifier} 时出错: ${error.message}`, this.getCurrentLine());
            this.skipUntilNextStatement();
        }
    }

    parseVersion() {
        this.consume('IDENTIFIER', '期望 VERSION');
        if (this.check('STRING')) {
            this.database.version = this.advance().value;
        }
    }

    parseNamespace() {
        this.consume('IDENTIFIER', '期望 NS_');
        this.consume('SEPARATOR', '期望 :');
        
        while (!this.isAtEnd() && !this.isNextStatement()) {
            if (this.check('IDENTIFIER')) {
                this.database.newSymbols.push(this.advance().value);
            } else {
                this.advance();
            }
        }
    }

    parseBitTiming() {
        this.consume('IDENTIFIER', '期望 BS_');
        this.consume('SEPARATOR', '期望 :');
        // 跳过位时序信息
        this.skipUntilNextStatement();
    }

    parseNodes() {
        this.consume('IDENTIFIER', '期望 BU_');
        this.consume('SEPARATOR', '期望 :');
        
        while (!this.isAtEnd() && !this.isNextStatement()) {
            if (this.check('IDENTIFIER')) {
                this.database.addNode(this.advance().value);
            } else {
                this.advance();
            }
        }
    }

    parseMessage() {
        this.consume('IDENTIFIER', '期望 BO_');
        
        const canId = this.consumeNumber('期望 CAN ID');
        const name = this.consume('IDENTIFIER', '期望消息名称').value;
        this.consume('SEPARATOR', '期望 :');
        const dlc = this.consumeNumber('期望 DLC');
        const transmitter = this.consume('IDENTIFIER', '期望发送节点').value;
        
        console.log('解析消息:', { canId, name, dlc, transmitter });
        
        const frame = new CANFrame(name, canId, dlc);
        frame.setTransmitters([transmitter]);
        this.database.addFrame(frame);
        
        // 解析信号
        let signalCount = 0;
        while (!this.isAtEnd() && this.check('IDENTIFIER') && this.peek().value === 'SG_') {
            this.parseSignalInMessage(frame);
            signalCount++;
        }
        
        console.log(`消息 ${name} 解析了 ${signalCount} 个信号`);
    }

    parseSignalInMessage(frame) {
        this.consume('IDENTIFIER', '期望 SG_');
        
        const signalName = this.consume('IDENTIFIER', '期望信号名称').value;
        
        // 检查多路复用信息
        let multiplexInfo = null;
        if (this.check('IDENTIFIER')) {
            const next = this.peek().value;
            if (next === 'M' || next.startsWith('m')) {
                multiplexInfo = this.advance().value;
            }
        }
        
        this.consume('SEPARATOR', '期望 :');
        
        const startBit = this.consumeNumber('期望起始位');
        this.consume('SEPARATOR', '期望 |');
        const length = this.consumeNumber('期望长度');
        this.consume('SEPARATOR', '期望 @');
        const byteOrder = this.consumeNumber('期望字节序');
        const signedness = this.consume('IDENTIFIER', '期望符号性').value;
        
        this.consume('SEPARATOR', '期望 (');
        const factor = this.consumeFloat('期望因子');
        this.consume('SEPARATOR', '期望 ,');
        const offset = this.consumeFloat('期望偏移');
        this.consume('SEPARATOR', '期望 )');
        
        this.consume('SEPARATOR', '期望 [');
        const min = this.consumeFloat('期望最小值');
        this.consume('SEPARATOR', '期望 |');
        const max = this.consumeFloat('期望最大值');
        this.consume('SEPARATOR', '期望 ]');
        
        const unit = this.consume('STRING', '期望单位').value;
        
        // 接收节点
        const receivers = [];
        while (!this.isAtEnd() && this.check('IDENTIFIER') && !this.isNextStatement()) {
            receivers.push(this.advance().value);
            if (this.check('SEPARATOR') && this.peek().value === ',') {
                this.advance();
            }
        }
        
        const signal = new CANSignal(
            signalName, startBit, length,
            byteOrder === 1 ? 'Intel' : 'Motorola',
            signedness === '+' ? 'unsigned' : 'signed',
            factor, offset, min, max, unit
        );
        
        if (multiplexInfo) {
            signal.setMultiplexInfo(multiplexInfo);
        }
        
        signal.receivers = receivers;
        frame.addSignal(signal);
    }

    parseComment() {
        this.consume('IDENTIFIER', '期望 CM_');
        
        if (this.check('IDENTIFIER')) {
            const type = this.advance().value;
            
            if (type === 'BO_') {
                // 消息注释
                const canId = this.consumeNumber('期望 CAN ID');
                const comment = this.consume('STRING', '期望注释').value;
                const frame = this.database.getFrame(canId);
                if (frame) {
                    frame.setComment(comment);
                }
            } else if (type === 'SG_') {
                // 信号注释
                const canId = this.consumeNumber('期望 CAN ID');
                const signalName = this.consume('IDENTIFIER', '期望信号名称').value;
                const comment = this.consume('STRING', '期望注释').value;
                const frame = this.database.getFrame(canId);
                if (frame && frame.hasSignal(signalName)) {
                    frame.getSignal(signalName).setComment(comment);
                }
            }
        }
        
        this.consume('SEPARATOR', '期望 ;');
    }

    parseAttributeDefinition() {
        this.skipUntilSemicolon();
    }

    parseAttributeValue() {
        this.skipUntilSemicolon();
    }

    parseValueTable() {
        this.consume('IDENTIFIER', '期望 VAL_');
        
        const canId = this.consumeNumber('期望 CAN ID');
        const signalName = this.consume('IDENTIFIER', '期望信号名称').value;
        
        const valueTable = new Map();
        
        while (!this.isAtEnd() && !this.check('SEPARATOR')) {
            if (this.check('NUMBER')) {
                const value = this.consumeNumber('期望值');
                const description = this.consume('STRING', '期望描述').value;
                valueTable.set(value, description);
            } else {
                this.advance();
            }
        }
        
        this.consume('SEPARATOR', '期望 ;');
        
        const frame = this.database.getFrame(canId);
        if (frame && frame.hasSignal(signalName)) {
            frame.getSignal(signalName).setValueTable(valueTable);
        }
    }

    parseTransmitters() {
        this.skipUntilSemicolon();
    }

    // 辅助方法
    consume(expectedType, message) {
        if (this.check(expectedType)) {
            return this.advance();
        }
        throw new Error(`${message}，但得到 ${this.peek().type}`);
    }

    consumeNumber(message) {
        const token = this.consume('NUMBER', message);
        return parseFloat(token.value);
    }

    consumeFloat(message) {
        const token = this.consume('NUMBER', message);
        return parseFloat(token.value);
    }

    check(type) {
        if (this.isAtEnd()) return false;
        return this.peek().type === type;
    }

    advance() {
        if (!this.isAtEnd()) this.current++;
        return this.previous();
    }

    isAtEnd() {
        return this.peek().type === 'EOF';
    }

    peek() {
        return this.tokens[this.current];
    }

    previous() {
        return this.tokens[this.current - 1];
    }

    getCurrentLine() {
        return this.peek().line;
    }

    isNextStatement() {
        if (this.isAtEnd()) return true;
        const keywords = ['VERSION', 'NS_', 'BS_', 'BU_', 'BO_', 'SG_', 'CM_', 'BA_DEF_', 'BA_', 'VAL_', 'BO_TX_BU_'];
        return keywords.includes(this.peek().value);
    }

    skipUntilNextStatement() {
        while (!this.isAtEnd() && !this.isNextStatement()) {
            this.advance();
        }
    }

    skipUntilSemicolon() {
        while (!this.isAtEnd() && !(this.check('SEPARATOR') && this.peek().value === ';')) {
            this.advance();
        }
        if (!this.isAtEnd()) this.advance(); // 跳过分号
    }
} 